//------------------------------------------------------------------------------
// The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at  http://www.nopCommerce.com/License.aspx. 
// 
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
// See the License for the specific language governing rights and limitations under the License.
// 
// The Original Code is nopCommerce.
// The Initial Developer of the Original Code is NopSolutions.
// All Rights Reserved.
// 
// Contributor(s): _______. 
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Compilation;
using System.Xml;
using NopSolutions.NopCommerce.Common.Categories;
using NopSolutions.NopCommerce.Common.CustomerManagement;
using NopSolutions.NopCommerce.Common.Directory;
using NopSolutions.NopCommerce.Common.Manufacturers;
using NopSolutions.NopCommerce.Common.Messages;
using NopSolutions.NopCommerce.Common.Orders;
using NopSolutions.NopCommerce.Common.Products;
using NopSolutions.NopCommerce.Common.Products.Attributes;
using NopSolutions.NopCommerce.Common.Products.Specs;
using NopSolutions.NopCommerce.Common.Promo.Discounts;
using NopSolutions.NopCommerce.Common.Security;
using NopSolutions.NopCommerce.Common.Shipping;
using NopSolutions.NopCommerce.Common.Utils;

namespace NopSolutions.NopCommerce.Common.ExportImport
{
    /// <summary>
    /// Export manager
    /// </summary>
    public class ExportManager
    {
        #region Utilities

        private static void WriteCategories(XmlWriter xmlWriter, int ParentCategoryID)
        {
            CategoryCollection categories = CategoryManager.GetAllCategories(ParentCategoryID);
            if (categories.Count > 0)
            {
                foreach (Category category in categories)
                {
                    xmlWriter.WriteStartElement("Category");
                    xmlWriter.WriteElementString("CategoryID", null, category.CategoryID.ToString());
                    xmlWriter.WriteElementString("Name", null, category.Name);
                    xmlWriter.WriteElementString("Description", null, category.Description);
                    xmlWriter.WriteElementString("TemplateID", null, category.TemplateID.ToString());
                    xmlWriter.WriteElementString("MetaKeywords", null, category.MetaKeywords);
                    xmlWriter.WriteElementString("MetaDescription", null, category.MetaDescription);
                    xmlWriter.WriteElementString("MetaTitle", null, category.MetaTitle);
                    xmlWriter.WriteElementString("SEName", null, category.SEName);
                    xmlWriter.WriteElementString("ParentCategoryID", null, category.ParentCategoryID.ToString());
                    xmlWriter.WriteElementString("PictureID", null, category.PictureID.ToString());
                    xmlWriter.WriteElementString("PageSize", null, category.PageSize.ToString());
                    xmlWriter.WriteElementString("PriceRanges", null, category.PriceRanges);
                    xmlWriter.WriteElementString("Published", null, category.Published.ToString());
                    xmlWriter.WriteElementString("Deleted", null, category.Deleted.ToString());
                    xmlWriter.WriteElementString("DisplayOrder", null, category.DisplayOrder.ToString());
                    xmlWriter.WriteElementString("CreatedOn", null, category.CreatedOn.ToString());
                    xmlWriter.WriteElementString("UpdatedOn", null, category.UpdatedOn.ToString());

                    xmlWriter.WriteStartElement("Products");
                    ProductCategoryCollection productCategories = category.ProductCategories;
                    foreach (ProductCategory productCategory in productCategories)
                    {
                        Product product = productCategory.Product;
                        if (product != null && !product.Deleted)
                        {
                            xmlWriter.WriteStartElement("ProductCategory");
                            xmlWriter.WriteElementString("ProductCategoryID", null, productCategory.ProductCategoryID.ToString());
                            xmlWriter.WriteElementString("ProductID", null, productCategory.ProductID.ToString());
                            xmlWriter.WriteElementString("IsFeaturedProduct", null, productCategory.IsFeaturedProduct.ToString());
                            xmlWriter.WriteElementString("DisplayOrder", null, productCategory.DisplayOrder.ToString());
                            xmlWriter.WriteEndElement();
                        }
                    }
                    xmlWriter.WriteEndElement();

                    xmlWriter.WriteStartElement("SubCategories");
                    WriteCategories(xmlWriter, category.CategoryID);
                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteEndElement();
                }
            }
        }

        #endregion

        #region Methods
        /// <summary>
        /// Export customer list to xml
        /// </summary>
        /// <returns>Result in XML format</returns>
        public static string ExportCustomersToXML()
        {
            CustomerCollection customers = CustomerManager.GetAllCustomers();
            return ExportCustomersToXML(customers);
        }

        /// <summary>
        /// Export customer list to xml
        /// </summary>
        /// <param name="customers">Customers</param>
        /// <returns>Result in XML format</returns>
        public static string ExportCustomersToXML(CustomerCollection customers)
        {
            StringBuilder sb = new StringBuilder();
            StringWriter stringWriter = new StringWriter(sb);
            XmlWriter xmlWriter = new XmlTextWriter(stringWriter);
            xmlWriter.WriteStartDocument();
            xmlWriter.WriteStartElement("Customers");
            xmlWriter.WriteAttributeString("Version", CommonHelper.GetCurrentVersion());

            foreach (Customer customer in customers)
            {
                xmlWriter.WriteStartElement("Customer");
                xmlWriter.WriteElementString("CustomerID", null, customer.CustomerID.ToString());
                xmlWriter.WriteElementString("CustomerGUID", null, customer.CustomerGUID.ToString());
                xmlWriter.WriteElementString("Email", null, customer.Email);
                xmlWriter.WriteElementString("Username", null, customer.Username);
                xmlWriter.WriteElementString("PasswordHash", null, customer.PasswordHash);
                xmlWriter.WriteElementString("SaltKey", null, customer.SaltKey);
                xmlWriter.WriteElementString("AffiliateID", null, customer.AffiliateID.ToString());
                xmlWriter.WriteElementString("BillingAddressID", null, customer.BillingAddressID.ToString());
                xmlWriter.WriteElementString("ShippingAddressID", null, customer.ShippingAddressID.ToString());
                xmlWriter.WriteElementString("LastPaymentMethodID", null, customer.LastPaymentMethodID.ToString());
                xmlWriter.WriteElementString("LastAppliedCouponCode", null, customer.LastAppliedCouponCode);
                xmlWriter.WriteElementString("LanguageID", null, customer.LanguageID.ToString());
                xmlWriter.WriteElementString("CurrencyID", null, customer.CurrencyID.ToString());
                xmlWriter.WriteElementString("TaxDisplayTypeID", null, customer.TaxDisplayTypeID.ToString());
                xmlWriter.WriteElementString("IsAdmin", null, customer.IsAdmin.ToString());
                xmlWriter.WriteElementString("IsGuest", null, customer.IsGuest.ToString());
                xmlWriter.WriteElementString("IsForumModerator", null, customer.IsForumModerator.ToString());
                xmlWriter.WriteElementString("TotalForumPosts", null, customer.TotalForumPosts.ToString());
                xmlWriter.WriteElementString("Active", null, customer.Active.ToString());
                xmlWriter.WriteElementString("Deleted", null, customer.Deleted.ToString());
                xmlWriter.WriteElementString("RegistrationDate", null, customer.RegistrationDate.ToString());
                xmlWriter.WriteElementString("TimeZoneID", null, customer.TimeZoneID);
                xmlWriter.WriteElementString("AvatarID", null, customer.AvatarID.ToString());


                xmlWriter.WriteElementString("Gender", null, customer.Gender);
                xmlWriter.WriteElementString("FirstName", null, customer.FirstName);
                xmlWriter.WriteElementString("LastName", null, customer.LastName);
                if (customer.DateOfBirth.HasValue)
                    xmlWriter.WriteElementString("DateOfBirth", null, customer.DateOfBirth.Value.ToBinary().ToString());
                xmlWriter.WriteElementString("Company", null, customer.Company);
                xmlWriter.WriteElementString("StreetAddress", null, customer.StreetAddress);
                xmlWriter.WriteElementString("StreetAddress2", null, customer.StreetAddress2);
                xmlWriter.WriteElementString("ZipPostalCode", null, customer.ZipPostalCode);
                xmlWriter.WriteElementString("City", null, customer.City);
                xmlWriter.WriteElementString("PhoneNumber", null, customer.PhoneNumber);
                xmlWriter.WriteElementString("FaxNumber", null, customer.FaxNumber);

                xmlWriter.WriteElementString("CountryID", null, customer.CountryID.ToString());
                Country country = CountryManager.GetCountryByID(customer.CountryID);
                xmlWriter.WriteElementString("Country", null, (country == null) ? string.Empty : country.Name);

                xmlWriter.WriteElementString("StateProvinceID", null, customer.StateProvinceID.ToString());
                StateProvince stateProvince = StateProvinceManager.GetStateProvinceByID(customer.StateProvinceID);
                xmlWriter.WriteElementString("StateProvince", null, (stateProvince == null) ? string.Empty : stateProvince.Name);
                xmlWriter.WriteElementString("ReceiveNewsletter", null, customer.ReceiveNewsletter.ToString());

                AddressCollection billingAddresses = customer.BillingAddresses;
                if (billingAddresses.Count > 0)
                {
                    xmlWriter.WriteStartElement("BillingAddresses");
                    foreach (Address address in billingAddresses)
                    {
                        xmlWriter.WriteStartElement("Address");
                        xmlWriter.WriteElementString("AddressID", null, address.AddressID.ToString());
                        xmlWriter.WriteElementString("FirstName", null, address.FirstName);
                        xmlWriter.WriteElementString("LastName", null, address.LastName);
                        xmlWriter.WriteElementString("PhoneNumber", null, address.PhoneNumber);
                        xmlWriter.WriteElementString("Email", null, address.Email);
                        xmlWriter.WriteElementString("FaxNumber", null, address.FaxNumber);
                        xmlWriter.WriteElementString("Company", null, address.Company);
                        xmlWriter.WriteElementString("Address1", null, address.Address1);
                        xmlWriter.WriteElementString("Address2", null, address.Address2);
                        xmlWriter.WriteElementString("City", null, address.City);
                        xmlWriter.WriteElementString("StateProvinceID", null, address.StateProvinceID.ToString());
                        xmlWriter.WriteElementString("StateProvince", null, (address.StateProvince == null) ? string.Empty : address.StateProvince.Name);
                        xmlWriter.WriteElementString("ZipPostalCode", null, address.ZipPostalCode);
                        xmlWriter.WriteElementString("CountryID", null, address.CountryID.ToString());
                        xmlWriter.WriteElementString("Country", null, (address.Country == null) ? string.Empty : address.Country.Name);
                        xmlWriter.WriteElementString("CreatedOn", null, address.CreatedOn.ToString());
                        xmlWriter.WriteEndElement();
                    }
                    xmlWriter.WriteEndElement();
                }

                AddressCollection shippingAddresses = customer.ShippingAddresses;
                if (shippingAddresses.Count > 0)
                {
                    xmlWriter.WriteStartElement("ShippingAddresses");
                    foreach (Address address in shippingAddresses)
                    {
                        xmlWriter.WriteStartElement("Address");
                        xmlWriter.WriteElementString("AddressID", null, address.AddressID.ToString());
                        xmlWriter.WriteElementString("FirstName", null, address.FirstName);
                        xmlWriter.WriteElementString("LastName", null, address.LastName);
                        xmlWriter.WriteElementString("PhoneNumber", null, address.PhoneNumber);
                        xmlWriter.WriteElementString("Email", null, address.Email);
                        xmlWriter.WriteElementString("FaxNumber", null, address.FaxNumber);
                        xmlWriter.WriteElementString("Company", null, address.Company);
                        xmlWriter.WriteElementString("Address1", null, address.Address1);
                        xmlWriter.WriteElementString("Address2", null, address.Address2);
                        xmlWriter.WriteElementString("City", null, address.City);
                        xmlWriter.WriteElementString("StateProvinceID", null, address.StateProvinceID.ToString());
                        xmlWriter.WriteElementString("StateProvince", null, (address.StateProvince == null) ? string.Empty : address.StateProvince.Name);
                        xmlWriter.WriteElementString("ZipPostalCode", null, address.ZipPostalCode);
                        xmlWriter.WriteElementString("CountryID", null, address.CountryID.ToString());
                        xmlWriter.WriteElementString("Country", null, (address.Country == null) ? string.Empty : address.Country.Name);
                        xmlWriter.WriteElementString("CreatedOn", null, address.CreatedOn.ToString());
                        xmlWriter.WriteEndElement();
                    }
                    xmlWriter.WriteEndElement();
                }
                xmlWriter.WriteEndElement();
            }

            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Close();
            return stringWriter.ToString();
        }

        /// <summary>
        /// Export manufacturer list to xml
        /// </summary>
        /// <returns>Result in XML format</returns>
        public static string ExportManufacturersToXML()
        {
            StringBuilder sb = new StringBuilder();
            StringWriter stringWriter = new StringWriter(sb);
            XmlWriter xmlWriter = new XmlTextWriter(stringWriter);
            xmlWriter.WriteStartDocument();
            xmlWriter.WriteStartElement("Manufacturers");
            xmlWriter.WriteAttributeString("Version", CommonHelper.GetCurrentVersion());

            ManufacturerCollection manufacturers = ManufacturerManager.GetAllManufacturers();
            foreach (Manufacturer manufacturer in manufacturers)
            {
                xmlWriter.WriteStartElement("Manufacturer");
                xmlWriter.WriteElementString("ManufacturerID", null, manufacturer.ManufacturerID.ToString());
                xmlWriter.WriteElementString("Name", null, manufacturer.Name);
                xmlWriter.WriteElementString("Description", null, manufacturer.Description);
                xmlWriter.WriteElementString("TemplateID", null, manufacturer.TemplateID.ToString());
                xmlWriter.WriteElementString("MetaKeywords", null, manufacturer.MetaKeywords);
                xmlWriter.WriteElementString("MetaDescription", null, manufacturer.MetaDescription);
                xmlWriter.WriteElementString("MetaTitle", null, manufacturer.MetaTitle);
                xmlWriter.WriteElementString("SEName", null, manufacturer.SEName);
                xmlWriter.WriteElementString("PictureID", null, manufacturer.PictureID.ToString());
                xmlWriter.WriteElementString("PageSize", null, manufacturer.PageSize.ToString());
                xmlWriter.WriteElementString("PriceRanges", null, manufacturer.PriceRanges);
                xmlWriter.WriteElementString("Published", null, manufacturer.Published.ToString());
                xmlWriter.WriteElementString("Deleted", null, manufacturer.Deleted.ToString());
                xmlWriter.WriteElementString("DisplayOrder", null, manufacturer.DisplayOrder.ToString());
                xmlWriter.WriteElementString("CreatedOn", null, manufacturer.CreatedOn.ToString());
                xmlWriter.WriteElementString("UpdatedOn", null, manufacturer.UpdatedOn.ToString());

                xmlWriter.WriteStartElement("Products");
                ProductManufacturerCollection productManufacturers = manufacturer.ProductManufacturers;
                foreach (ProductManufacturer productManufacturer in productManufacturers)
                {
                    Product product = productManufacturer.Product;
                    if (product != null && !product.Deleted)
                    {
                        xmlWriter.WriteStartElement("ProductManufacturer");
                        xmlWriter.WriteElementString("ProductManufacturerID", null, productManufacturer.ProductManufacturerID.ToString());
                        xmlWriter.WriteElementString("ProductID", null, productManufacturer.ProductID.ToString());
                        xmlWriter.WriteElementString("IsFeaturedProduct", null, productManufacturer.IsFeaturedProduct.ToString());
                        xmlWriter.WriteElementString("DisplayOrder", null, productManufacturer.DisplayOrder.ToString());
                        xmlWriter.WriteEndElement();
                    }
                }
                xmlWriter.WriteEndElement();

                xmlWriter.WriteEndElement();
            }

            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Close();
            return stringWriter.ToString();
        }

        /// <summary>
        /// Export category list to xml
        /// </summary>
        /// <returns>Result in XML format</returns>
        public static string ExportCategoriesToXML()
        {
            StringBuilder sb = new StringBuilder();
            StringWriter stringWriter = new StringWriter(sb);
            XmlWriter xmlWriter = new XmlTextWriter(stringWriter);
            xmlWriter.WriteStartDocument();
            xmlWriter.WriteStartElement("Categories");
            xmlWriter.WriteAttributeString("Version", CommonHelper.GetCurrentVersion());
            WriteCategories(xmlWriter, 0);
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Close();
            return stringWriter.ToString();
        }

        /// <summary>
        /// Export product list to xml
        /// </summary>
        /// <returns>Result in XML format</returns>
        public static string ExportProductsToXML()
        {
            ProductCollection products = ProductManager.GetAllProducts();
            return ExportProductsToXML(products);
        }

        /// <summary>
        /// Export product list to xml
        /// </summary>
        /// <param name="products">Products</param>
        /// <returns>Result in XML format</returns>
        public static string ExportProductsToXML(ProductCollection products)
        {
            StringBuilder sb = new StringBuilder();
            StringWriter stringWriter = new StringWriter(sb);
            XmlWriter xmlWriter = new XmlTextWriter(stringWriter);
            xmlWriter.WriteStartDocument();
            xmlWriter.WriteStartElement("Products");
            xmlWriter.WriteAttributeString("Version", CommonHelper.GetCurrentVersion());
            
            foreach (Product product in products)
            {
                xmlWriter.WriteStartElement("Product");
                xmlWriter.WriteElementString("ProductID", null, product.ProductID.ToString());
                xmlWriter.WriteElementString("Name", null, product.Name);
                xmlWriter.WriteElementString("ShortDescription", null, product.ShortDescription);
                xmlWriter.WriteElementString("FullDescription", null, product.FullDescription);
                xmlWriter.WriteElementString("AdminComment", null, product.AdminComment);
                xmlWriter.WriteElementString("ProductTypeID", null, product.ProductTypeID.ToString());
                xmlWriter.WriteElementString("TemplateID", null, product.TemplateID.ToString());
                xmlWriter.WriteElementString("ShowOnHomePage", null, product.ShowOnHomePage.ToString());
                xmlWriter.WriteElementString("MetaKeywords", null, product.MetaKeywords);
                xmlWriter.WriteElementString("MetaDescription", null, product.MetaDescription);
                xmlWriter.WriteElementString("MetaTitle", null, product.MetaTitle);
                xmlWriter.WriteElementString("SEName", null, product.SEName);
                xmlWriter.WriteElementString("AllowCustomerReviews", null, product.AllowCustomerReviews.ToString());
                xmlWriter.WriteElementString("AllowCustomerRatings", null, product.AllowCustomerRatings.ToString());
                xmlWriter.WriteElementString("RatingSum", null, product.RatingSum.ToString());
                xmlWriter.WriteElementString("TotalRatingVotes", null, product.TotalRatingVotes.ToString());
                xmlWriter.WriteElementString("Published", null, product.Published.ToString());
                xmlWriter.WriteElementString("Deleted", null, product.Deleted.ToString());
                xmlWriter.WriteElementString("CreatedOn", null, product.CreatedOn.ToString());
                xmlWriter.WriteElementString("UpdatedOn", null, product.UpdatedOn.ToString());

                xmlWriter.WriteStartElement("ProductVariants");
                ProductVariantCollection productVariants = product.ProductVariants;
                foreach (ProductVariant productVariant in productVariants)
                {
                    xmlWriter.WriteStartElement("ProductVariant");
                    xmlWriter.WriteElementString("ProductVariantID", null, productVariant.ProductVariantID.ToString());
                    xmlWriter.WriteElementString("ProductID", null, productVariant.ProductID.ToString());
                    xmlWriter.WriteElementString("Name", null, productVariant.Name);
                    xmlWriter.WriteElementString("SKU", null, productVariant.SKU);
                    xmlWriter.WriteElementString("Description", null, productVariant.Description);
                    xmlWriter.WriteElementString("AdminComment", null, productVariant.AdminComment);
                    xmlWriter.WriteElementString("ManufacturerPartNumber", null, productVariant.ManufacturerPartNumber);
                    xmlWriter.WriteElementString("IsDownload", null, productVariant.IsDownload.ToString());
                    xmlWriter.WriteElementString("DownloadID", null, productVariant.DownloadID.ToString());
                    xmlWriter.WriteElementString("IsShipEnabled", null, productVariant.IsShipEnabled.ToString());
                    xmlWriter.WriteElementString("IsFreeShipping", null, productVariant.IsFreeShipping.ToString());
                    xmlWriter.WriteElementString("AdditionalShippingCharge", null, productVariant.AdditionalShippingCharge.ToString());
                    xmlWriter.WriteElementString("IsTaxExempt", null, productVariant.IsTaxExempt.ToString());
                    xmlWriter.WriteElementString("TaxCategoryID", null, productVariant.TaxCategoryID.ToString());
                    xmlWriter.WriteElementString("ManageInventory", null, productVariant.ManageInventory.ToString());
                    xmlWriter.WriteElementString("StockQuantity", null, productVariant.StockQuantity.ToString());
                    xmlWriter.WriteElementString("MinStockQuantity", null, productVariant.MinStockQuantity.ToString());
                    xmlWriter.WriteElementString("LowStockActivityID", null, productVariant.LowStockActivityID.ToString());
                    xmlWriter.WriteElementString("NotifyAdminForQuantityBelow", null, productVariant.NotifyAdminForQuantityBelow.ToString());
                    xmlWriter.WriteElementString("OrderMinimumQuantity", null, productVariant.OrderMinimumQuantity.ToString());
                    xmlWriter.WriteElementString("OrderMaximumQuantity", null, productVariant.OrderMaximumQuantity.ToString());
                    xmlWriter.WriteElementString("WarehouseId", null, productVariant.WarehouseId.ToString());
                    xmlWriter.WriteElementString("DisableBuyButton", null, productVariant.DisableBuyButton.ToString());
                    xmlWriter.WriteElementString("RequiresTextOption", null, productVariant.RequiresTextOption.ToString());
                    xmlWriter.WriteElementString("TextOptionPrompt", null, productVariant.TextOptionPrompt);
                    xmlWriter.WriteElementString("Price", null, productVariant.Price.ToString());
                    xmlWriter.WriteElementString("OldPrice", null, productVariant.OldPrice.ToString());
                    xmlWriter.WriteElementString("Weight", null, productVariant.Weight.ToString());
                    xmlWriter.WriteElementString("Length", null, productVariant.Length.ToString());
                    xmlWriter.WriteElementString("Width", null, productVariant.Width.ToString());
                    xmlWriter.WriteElementString("Height", null, productVariant.Height.ToString());
                    xmlWriter.WriteElementString("PictureID", null, productVariant.PictureID.ToString());
                    xmlWriter.WriteElementString("Published", null, productVariant.Published.ToString());
                    xmlWriter.WriteElementString("Deleted", null, productVariant.Deleted.ToString());
                    xmlWriter.WriteElementString("DisplayOrder", null, productVariant.DisplayOrder.ToString());
                    xmlWriter.WriteElementString("CreatedOn", null, productVariant.CreatedOn.ToString());
                    xmlWriter.WriteElementString("UpdatedOn", null, productVariant.UpdatedOn.ToString());

                    xmlWriter.WriteStartElement("ProductDiscounts");
                    DiscountCollection discounts = productVariant.AllDiscounts;
                    foreach (Discount discount in discounts)
                    {
                        xmlWriter.WriteElementString("DiscountID", null, discount.DiscountID.ToString());
                    }
                    xmlWriter.WriteEndElement();


                    xmlWriter.WriteStartElement("TierPrices");
                    TierPriceCollection tierPrices = productVariant.TierPrices;
                    foreach (TierPrice tierPrice in tierPrices)
                    {
                        xmlWriter.WriteElementString("TierPriceID", null, tierPrice.TierPriceID.ToString());
                        xmlWriter.WriteElementString("Quantity", null, tierPrice.Quantity.ToString());
                        xmlWriter.WriteElementString("Price", null, tierPrice.Price.ToString());
                    }
                    xmlWriter.WriteEndElement();

                    xmlWriter.WriteStartElement("ProductAttributes");
                    ProductVariantAttributeCollection productVariantAttributes = productVariant.ProductVariantAttributes;
                    foreach (ProductVariantAttribute productVariantAttribute in productVariantAttributes)
                    {
                        xmlWriter.WriteStartElement("ProductVariantAttribute");
                        xmlWriter.WriteElementString("ProductVariantAttributeID", null, productVariantAttribute.ProductVariantAttributeID.ToString());
                        xmlWriter.WriteElementString("ProductAttributeID", null, productVariantAttribute.ProductAttributeID.ToString());
                        xmlWriter.WriteElementString("IsRequired", null, productVariantAttribute.IsRequired.ToString());
                        xmlWriter.WriteElementString("AttributeControlTypeID", null, productVariantAttribute.AttributeControlTypeID.ToString());
                        xmlWriter.WriteElementString("DisplayOrder", null, productVariantAttribute.DisplayOrder.ToString());




                        xmlWriter.WriteStartElement("ProductVariantAttributeValues");
                        ProductVariantAttributeValueCollection productVariantAttributeValues = productVariantAttribute.ProductVariantAttributeValues;
                        foreach (ProductVariantAttributeValue productVariantAttributeValue in productVariantAttributeValues)
                        {
                            xmlWriter.WriteElementString("ProductVariantAttributeValueID", null, productVariantAttributeValue.ProductVariantAttributeValueID.ToString());
                            xmlWriter.WriteElementString("Name", null, productVariantAttributeValue.Name);
                            xmlWriter.WriteElementString("PriceAdjustment", null, productVariantAttributeValue.PriceAdjustment.ToString());
                            xmlWriter.WriteElementString("WeightAdjustment", null, productVariantAttributeValue.WeightAdjustment.ToString());
                            xmlWriter.WriteElementString("IsPreSelected", null, productVariantAttributeValue.IsPreSelected.ToString());
                            xmlWriter.WriteElementString("DisplayOrder", null, productVariantAttributeValue.DisplayOrder.ToString());
                        }
                        xmlWriter.WriteEndElement();






                        xmlWriter.WriteEndElement();
                    }
                    xmlWriter.WriteEndElement();



                    xmlWriter.WriteEndElement();
                }
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement("ProductPictures");
                ProductPictureCollection productPictures = product.ProductPictures;
                foreach (ProductPicture productPicture in productPictures)
                {
                    xmlWriter.WriteStartElement("ProductPicture");
                    xmlWriter.WriteElementString("ProductPictureID", null, productPicture.ProductPictureID.ToString());
                    xmlWriter.WriteElementString("PictureID", null, productPicture.PictureID.ToString());
                    xmlWriter.WriteElementString("DisplayOrder", null, productPicture.DisplayOrder.ToString());
                    xmlWriter.WriteEndElement();
                }
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement("RelatedProducts");
                RelatedProductCollection relatedProducts = product.RelatedProducts;
                foreach (RelatedProduct relatedProduct in relatedProducts)
                {
                    xmlWriter.WriteStartElement("RelatedProduct");
                    xmlWriter.WriteElementString("RelatedProductID", null, relatedProduct.RelatedProductID.ToString());
                    xmlWriter.WriteElementString("ProductID1", null, relatedProduct.ProductID1.ToString());
                    xmlWriter.WriteElementString("ProductID2", null, relatedProduct.ProductID2.ToString());
                    xmlWriter.WriteElementString("DisplayOrder", null, relatedProduct.DisplayOrder.ToString());
                    xmlWriter.WriteEndElement();
                }
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement("ProductCategories");
                ProductCategoryCollection productCategories = product.ProductCategories;
                foreach (ProductCategory productCategory in productCategories)
                {
                    xmlWriter.WriteStartElement("ProductCategory");
                    xmlWriter.WriteElementString("ProductCategoryID", null, productCategory.ProductCategoryID.ToString());
                    xmlWriter.WriteElementString("CategoryID", null, productCategory.CategoryID.ToString());
                    xmlWriter.WriteElementString("IsFeaturedProduct", null, productCategory.IsFeaturedProduct.ToString());
                    xmlWriter.WriteElementString("DisplayOrder", null, productCategory.DisplayOrder.ToString());
                    xmlWriter.WriteEndElement();
                }
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement("ProductManufacturers");
                ProductManufacturerCollection productManufacturers = product.ProductManufacturers;
                foreach (ProductManufacturer productManufacturer in productManufacturers)
                {
                    xmlWriter.WriteStartElement("ProductManufacturer");
                    xmlWriter.WriteElementString("ProductManufacturerID", null, productManufacturer.ProductManufacturerID.ToString());
                    xmlWriter.WriteElementString("ManufacturerID", null, productManufacturer.ManufacturerID.ToString());
                    xmlWriter.WriteElementString("IsFeaturedProduct", null, productManufacturer.IsFeaturedProduct.ToString());
                    xmlWriter.WriteElementString("DisplayOrder", null, productManufacturer.DisplayOrder.ToString());
                    xmlWriter.WriteEndElement();
                }
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement("ProductSpecificationAttributes");
                ProductSpecificationAttributeCollection productSpecificationAttributes = product.ProductSpecificationAttributes;
                foreach (ProductSpecificationAttribute productSpecificationAttribute in productSpecificationAttributes)
                {
                    xmlWriter.WriteStartElement("ProductSpecificationAttribute");
                    xmlWriter.WriteElementString("ProductSpecificationAttributeID", null, productSpecificationAttribute.ProductSpecificationAttributeID.ToString());
                    xmlWriter.WriteElementString("SpecificationAttributeID", null, productSpecificationAttribute.SpecificationAttributeID.ToString());
                    xmlWriter.WriteElementString("AttributeValue", null, productSpecificationAttribute.AttributeValue);
                    xmlWriter.WriteElementString("DisplayOrder", null, productSpecificationAttribute.DisplayOrder.ToString());
                    xmlWriter.WriteEndElement();
                }
                xmlWriter.WriteEndElement();




                xmlWriter.WriteEndElement();
            }

            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Close();
            return stringWriter.ToString();
        }

        /// <summary>
        /// Export order list to xml
        /// </summary>
        /// <returns>Result in XML format</returns>
        public static string ExportOrdersToXML()
        {
            OrderCollection orders = OrderManager.LoadAllOrders();
            return ExportOrdersToXML(orders);
        }

        /// <summary>
        /// Export order list to xml
        /// </summary>
        /// <param name="orders">Orders</param>
        /// <returns>Result in XML format</returns>
        public static string ExportOrdersToXML(OrderCollection orders)
        {
            StringBuilder sb = new StringBuilder();
            StringWriter stringWriter = new StringWriter(sb);
            XmlWriter xmlWriter = new XmlTextWriter(stringWriter);
            xmlWriter.WriteStartDocument();
            xmlWriter.WriteStartElement("Orders");
            xmlWriter.WriteAttributeString("Version", CommonHelper.GetCurrentVersion());

            foreach (Order order in orders)
            {
                xmlWriter.WriteStartElement("Order");
                xmlWriter.WriteElementString("OrderID", null, order.OrderID.ToString());
                xmlWriter.WriteElementString("OrderGUID", null, order.OrderGUID.ToString());
                xmlWriter.WriteElementString("CustomerID", null, order.CustomerID.ToString());
                xmlWriter.WriteElementString("CustomerLanguageID", null, order.CustomerLanguageID.ToString());
                xmlWriter.WriteElementString("CustomerTaxDisplayTypeID", null, order.CustomerTaxDisplayTypeID.ToString());
                xmlWriter.WriteElementString("OrderSubtotalInclTax", null, order.OrderSubtotalInclTax.ToString());
                xmlWriter.WriteElementString("OrderSubtotalExclTax", null, order.OrderSubtotalExclTax.ToString());
                xmlWriter.WriteElementString("OrderShippingInclTax", null, order.OrderShippingInclTax.ToString());
                xmlWriter.WriteElementString("OrderShippingExclTax", null, order.OrderShippingExclTax.ToString());
                xmlWriter.WriteElementString("PaymentMethodAdditionalFeeInclTax", null, order.PaymentMethodAdditionalFeeInclTax.ToString());
                xmlWriter.WriteElementString("PaymentMethodAdditionalFeeExclTax", null, order.PaymentMethodAdditionalFeeExclTax.ToString());
                xmlWriter.WriteElementString("OrderTax", null, order.OrderTax.ToString());
                xmlWriter.WriteElementString("OrderTotal", null, order.OrderTotal.ToString());
                xmlWriter.WriteElementString("OrderDiscount", null, order.OrderDiscount.ToString());
                xmlWriter.WriteElementString("OrderSubtotalInclTaxInCustomerCurrency", null, order.OrderSubtotalInclTaxInCustomerCurrency.ToString());
                xmlWriter.WriteElementString("OrderSubtotalExclTaxInCustomerCurrency", null, order.OrderSubtotalExclTaxInCustomerCurrency.ToString());
                xmlWriter.WriteElementString("OrderShippingInclTaxInCustomerCurrency", null, order.OrderShippingInclTaxInCustomerCurrency.ToString());
                xmlWriter.WriteElementString("OrderShippingExclTaxInCustomerCurrency", null, order.OrderShippingExclTaxInCustomerCurrency.ToString());
                xmlWriter.WriteElementString("PaymentMethodAdditionalFeeInclTaxInCustomerCurrency", null, order.PaymentMethodAdditionalFeeInclTaxInCustomerCurrency.ToString());
                xmlWriter.WriteElementString("PaymentMethodAdditionalFeeExclTaxInCustomerCurrency", null, order.PaymentMethodAdditionalFeeExclTaxInCustomerCurrency.ToString());
                xmlWriter.WriteElementString("OrderTaxInCustomerCurrency", null, order.OrderTaxInCustomerCurrency.ToString());
                xmlWriter.WriteElementString("OrderTotalInCustomerCurrency", null, order.OrderTotalInCustomerCurrency.ToString());
                xmlWriter.WriteElementString("CustomerCurrencyCode", null, order.CustomerCurrencyCode);
                xmlWriter.WriteElementString("OrderWeight", null, order.OrderWeight.ToString());
                xmlWriter.WriteElementString("AffiliateID", null, order.AffiliateID.ToString());
                xmlWriter.WriteElementString("OrderStatusID", null, order.OrderStatusID.ToString());
                xmlWriter.WriteElementString("CardType", null, order.CardType);
                xmlWriter.WriteElementString("CardName", null, order.CardName);
                xmlWriter.WriteElementString("CardNumber", null, order.CardNumber);
                xmlWriter.WriteElementString("CardCVV2", null, order.CardCVV2);
                xmlWriter.WriteElementString("CardExpirationMonth", null, order.CardExpirationMonth);
                xmlWriter.WriteElementString("CardExpirationYear", null, order.CardExpirationYear);
                xmlWriter.WriteElementString("PaymentMethodID", null, order.PaymentMethodID.ToString());
                xmlWriter.WriteElementString("PaymentMethodName", null, order.PaymentMethodName);
                xmlWriter.WriteElementString("AuthorizationTransactionID", null, order.AuthorizationTransactionID);
                xmlWriter.WriteElementString("AuthorizationTransactionCode", null, order.AuthorizationTransactionCode);
                xmlWriter.WriteElementString("AuthorizationTransactionResult", null, order.AuthorizationTransactionResult);
                xmlWriter.WriteElementString("CaptureTransactionID", null, order.CaptureTransactionID);
                xmlWriter.WriteElementString("CaptureTransactionResult", null, order.CaptureTransactionResult);
                xmlWriter.WriteElementString("PurchaseOrderNumber", null, order.PurchaseOrderNumber);
                xmlWriter.WriteElementString("PaymentStatusID", null, order.PaymentStatusID.ToString());
                xmlWriter.WriteElementString("BillingFirstName", null, order.BillingFirstName);
                xmlWriter.WriteElementString("BillingLastName", null, order.BillingLastName);
                xmlWriter.WriteElementString("BillingPhoneNumber", null, order.BillingPhoneNumber);
                xmlWriter.WriteElementString("BillingEmail", null, order.BillingEmail);
                xmlWriter.WriteElementString("BillingFaxNumber", null, order.BillingFaxNumber);
                xmlWriter.WriteElementString("BillingCompany", null, order.BillingCompany);
                xmlWriter.WriteElementString("BillingAddress1", null, order.BillingAddress1);
                xmlWriter.WriteElementString("BillingAddress2", null, order.BillingAddress2);
                xmlWriter.WriteElementString("BillingCity", null, order.BillingCity);
                xmlWriter.WriteElementString("BillingStateProvince", null, order.BillingStateProvince);
                xmlWriter.WriteElementString("BillingStateProvinceID", null, order.BillingStateProvinceID.ToString());
                xmlWriter.WriteElementString("BillingCountry", null, order.BillingCountry);
                xmlWriter.WriteElementString("BillingCountryID", null, order.BillingCountryID.ToString());
                xmlWriter.WriteElementString("BillingZipPostalCode", null, order.BillingZipPostalCode);
                xmlWriter.WriteElementString("ShippingStatusID", null, order.ShippingStatusID.ToString());
                xmlWriter.WriteElementString("ShippingFirstName", null, order.ShippingFirstName);
                xmlWriter.WriteElementString("ShippingLastName", null, order.ShippingLastName);
                xmlWriter.WriteElementString("ShippingPhoneNumber", null, order.ShippingPhoneNumber);
                xmlWriter.WriteElementString("ShippingEmail", null, order.ShippingEmail);
                xmlWriter.WriteElementString("ShippingFaxNumber", null, order.ShippingFaxNumber);
                xmlWriter.WriteElementString("ShippingCompany", null, order.ShippingCompany);
                xmlWriter.WriteElementString("ShippingAddress1", null, order.ShippingAddress1);
                xmlWriter.WriteElementString("ShippingAddress2", null, order.ShippingAddress2);
                xmlWriter.WriteElementString("ShippingCity", null, order.ShippingCity);
                xmlWriter.WriteElementString("ShippingStateProvince", null, order.ShippingStateProvince);
                xmlWriter.WriteElementString("ShippingStateProvinceID", null, order.ShippingStateProvinceID.ToString());
                xmlWriter.WriteElementString("ShippingCountry", null, order.ShippingCountry);
                xmlWriter.WriteElementString("ShippingCountryID", null, order.ShippingCountryID.ToString());
                xmlWriter.WriteElementString("ShippingZipPostalCode", null, order.ShippingZipPostalCode);
                xmlWriter.WriteElementString("ShippingMethod", null, order.ShippingMethod);
                xmlWriter.WriteElementString("ShippingRateComputationMethodID", null, order.ShippingRateComputationMethodID.ToString());
                xmlWriter.WriteElementString("ShippedDate", null, (order.ShippedDate == null) ? string.Empty : order.ShippedDate.Value.ToString());
                xmlWriter.WriteElementString("Deleted", null, order.Deleted.ToString());
                xmlWriter.WriteElementString("CreatedOn", null, order.CreatedOn.ToString());

                OrderProductVariantCollection orderProductVariants = order.OrderProductVariants;
                if (orderProductVariants.Count > 0)
                {
                    xmlWriter.WriteStartElement("OrderProductVariants");
                    foreach (OrderProductVariant orderProductVariant in orderProductVariants)
                    {
                        xmlWriter.WriteStartElement("OrderProductVariant");
                        xmlWriter.WriteElementString("OrderProductVariantID", null, orderProductVariant.OrderProductVariantID.ToString());
                        xmlWriter.WriteElementString("ProductVariantID", null, orderProductVariant.ProductVariantID.ToString());

                        ProductVariant productVariant = orderProductVariant.ProductVariant;
                        if (productVariant != null)
                            xmlWriter.WriteElementString("ProductVariantName", null, productVariant.FullProductName);


                        xmlWriter.WriteElementString("UnitPriceInclTax", null, orderProductVariant.UnitPriceInclTax.ToString());
                        xmlWriter.WriteElementString("UnitPriceExclTax", null, orderProductVariant.UnitPriceExclTax.ToString());
                        xmlWriter.WriteElementString("PriceInclTax", null, orderProductVariant.PriceInclTax.ToString());
                        xmlWriter.WriteElementString("PriceExclTax", null, orderProductVariant.PriceExclTax.ToString());
                        xmlWriter.WriteElementString("UnitPriceInclTaxInCustomerCurrency", null, orderProductVariant.UnitPriceInclTaxInCustomerCurrency.ToString());
                        xmlWriter.WriteElementString("UnitPriceExclTaxInCustomerCurrency", null, orderProductVariant.UnitPriceExclTaxInCustomerCurrency.ToString());
                        xmlWriter.WriteElementString("PriceInclTaxInCustomerCurrency", null, orderProductVariant.PriceInclTaxInCustomerCurrency.ToString());
                        xmlWriter.WriteElementString("PriceExclTaxInCustomerCurrency", null, orderProductVariant.PriceExclTaxInCustomerCurrency.ToString());
                        xmlWriter.WriteElementString("AttributeDescription", null, orderProductVariant.AttributeDescription);
                        xmlWriter.WriteElementString("TextOption", null, orderProductVariant.TextOption);
                        xmlWriter.WriteElementString("Quantity", null, orderProductVariant.Quantity.ToString());
                        xmlWriter.WriteElementString("DiscountAmountInclTax", null, orderProductVariant.DiscountAmountInclTax.ToString());
                        xmlWriter.WriteElementString("DiscountAmountExclTax", null, orderProductVariant.DiscountAmountExclTax.ToString());
                        xmlWriter.WriteEndElement();
                    }
                    xmlWriter.WriteEndElement();
                }

                xmlWriter.WriteEndElement();
            }

            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Close();
            return stringWriter.ToString();
        }

        /// <summary>
        /// Export message tokens to xml
        /// </summary>
        /// <returns>Result in XML format</returns>
        public static string ExportMessageTokensToXML()
        {
            StringBuilder sb = new StringBuilder();
            StringWriter stringWriter = new StringWriter(sb);
            XmlWriter xmlWriter = new XmlTextWriter(stringWriter);
            xmlWriter.WriteStartDocument();
            xmlWriter.WriteStartElement("Tokens");
            string[] allowedTokens = MessageManager.GetListOfAllowedTokens();
            for (int i = 0; i < allowedTokens.Length; i++)
            {
                string token = allowedTokens[i];
                string tokenName = token.Replace("%", "");
                xmlWriter.WriteStartElement("Token");
                xmlWriter.WriteAttributeString("name", tokenName);
                xmlWriter.WriteAttributeString("value", token);
                xmlWriter.WriteEndElement();
            }
            xmlWriter.WriteEndElement();
            xmlWriter.Close();
            return stringWriter.ToString();
        }

        #endregion
    }
}
